home *** CD-ROM | disk | FTP | other *** search
- /* advprs.c - adventure parser */
- /*
- Copyright (c) 1986, by David Michael Betz
- All rights reserved
- */
-
- #include "advint.h"
- #include "advdbs.h"
-
- /* parser result variables */
- int nouns[20];
- int *adjectives[20];
- static int actor,action,dobject,ndobjects,iobject;
- static int flag;
-
- /* external routines */
- extern char *trm_get();
-
- /* external variables */
- extern char line[]; /* line buffer */
-
- /* local variables */
- static char *lptr; /* line pointer */
- static int words[100]; /* word table */
- static char *wtext[100];/* word text table */
- static int *wptr; /* word pointer */
- static int wcnt; /* word count */
-
- static int verbs[3]; /* words in the verb phrase */
- static int nnums[20]; /* noun word numbers */
- static int nptr; /* noun pointer (actually, an index) */
- static int adjs[100]; /* adjective lists */
- static int anums[100]; /* adjective word numbers */
- static int aptr; /* adjective pointer (actually, an index) */
-
- /* parse - read and parse an input line */
- int parse()
- {
- if (!parse1())
- return (FALSE);
- setvalue(V_ACTOR,actor);
- setvalue(V_ACTION,action);
- setvalue(V_DOBJECT,dobject);
- setvalue(V_NDOBJECTS,ndobjects);
- setvalue(V_IOBJECT,iobject);
- return (TRUE);
- }
-
- /* next - get the next command (next direct object) */
- int next()
- {
- if (getvalue(V_NDOBJECTS) > 1) {
- setvalue(V_ACTOR,actor);
- setvalue(V_ACTION,action);
- setvalue(V_DOBJECT,getvalue(V_DOBJECT) + 1);
- setvalue(V_NDOBJECTS,getvalue(V_NDOBJECTS) - 1);
- setvalue(V_IOBJECT,iobject);
- return (TRUE);
- }
- else
- return (FALSE);
- }
-
- /* parse1 - the main parser */
- int parse1()
- {
- int noun1,cnt1,noun2,cnt2;
- int preposition,flag;
-
- /* initialize */
- noun1 = noun2 = NIL; cnt1 = cnt2 = 0;
- nptr = aptr = 0;
- preposition = 0;
- flag = 0;
-
- /* initialize the parser result variables */
- actor = action = dobject = iobject = NIL;
- ndobjects = 0;
-
- /* get an input line */
- if (!get_line())
- return (FALSE);
-
- /* check for actor */
- if (wtype(*wptr) == WT_ADJECTIVE || wtype(*wptr) == WT_NOUN) {
- if ((actor = getnoun()) == NIL)
- return (FALSE);
- flag |= A_ACTOR;
- }
-
- /* get verb phrase */
- if (!getverb())
- return (FALSE);
-
- /* direct object, preposition and indirect object */
- if (*wptr) {
-
- /* get the first set of noun phrases (direct objects) */
- noun1 = nptr+1;
- for (;;) {
-
- /* get the next direct object */
- if (getnoun() == NIL)
- return (FALSE);
- ++cnt1;
-
- /* check for more direct objects */
- if (*wptr == NIL || wtype(*wptr) != WT_CONJUNCTION)
- break;
- wptr++;
- }
-
- /* get the preposition and indirect object */
- if (*wptr) {
-
- /* get the preposition */
- if (wtype(*wptr) == WT_PREPOSITION)
- preposition = *wptr++;
-
- /* get the second set of noun phrases (indirect object) */
- noun2 = nptr+1;
- for (;;) {
-
- /* get the next direct object */
- if (getnoun() == NIL)
- return (FALSE);
- ++cnt2;
-
- /* check for more direct objects */
- if (*wptr == NIL || wtype(*wptr) != WT_CONJUNCTION)
- break;
- wptr++;
- }
- }
-
- /* make sure this is the end of the sentence */
- if (*wptr) {
- parse_error();
- return (FALSE);
- }
- }
-
- /* setup the direct and indirect objects */
- if (preposition) {
- if (cnt2 > 1) {
- parse_error();
- return (FALSE);
- }
- dobject = noun1;
- ndobjects = cnt1;
- iobject = noun2;
- }
- else if (noun2) {
- if (cnt1 > 1) {
- parse_error();
- return (FALSE);
- }
- preposition = findword("to");
- dobject = noun2;
- ndobjects = cnt2;
- iobject = noun1;
- }
- else {
- dobject = noun1;
- ndobjects = cnt1;
- }
-
- /* setup the flags for the action lookup */
- if (dobject) flag |= A_DOBJECT;
- if (iobject) flag |= A_IOBJECT;
-
- /* find the action */
- if ((action = findaction(verbs,preposition,flag)) == NIL) {
- parse_error();
- return (FALSE);
- }
-
- /* return successfully */
- return (TRUE);
- }
-
- /* getverb - get a verb phrase and return the action it refers to */
- int getverb()
- {
- /* get the verb */
- if (*wptr == NIL || wtype(*wptr) != WT_VERB) {
- parse_error();
- return (NIL);
- }
- verbs[0] = *wptr++;
- verbs[1] = NIL;
-
- /* check for a word following the verb */
- if (*wptr) {
- verbs[1] = *wptr;
- verbs[2] = NIL;
- if (checkverb(verbs))
- wptr++;
- else {
- verbs[1] = words[wcnt-1];
- if (checkverb(verbs))
- words[--wcnt] = NIL;
- else {
- verbs[1] = NIL;
- if (!checkverb(verbs)) {
- parse_error();
- return (NIL);
- }
- }
- }
- }
- return (T);
- }
-
- /* getnoun - get a noun phrase and return the object it refers to */
- int getnoun()
- {
- /* initialize the adjective list pointer */
- adjectives[nptr] = adjs + aptr;
-
- /* get the optional article */
- if (*wptr != NIL && wtype(*wptr) == WT_ARTICLE)
- wptr++;
-
- /* get optional adjectives */
- while (*wptr != NIL && wtype(*wptr) == WT_ADJECTIVE) {
- adjs[aptr] = *wptr++;
- anums[aptr] = wptr - words - 1;
- aptr++;
- }
- adjs[aptr++] = NULL;
-
- /* get the noun itself */
- if (*wptr == NIL || wtype(*wptr) != WT_NOUN) {
- parse_error();
- return (NIL);
- }
-
- /* save the noun */
- nouns[nptr] = *wptr++;
- nnums[nptr] = wptr - words - 1;
- return (++nptr);
- }
-
- /* get_line - get the input line and lookup each word */
- int get_line()
- {
- /* read an input line */
- trm_chr(':');
- if ((lptr = trm_get(line)) == NULL) {
- trm_str("Speak up! I can't hear you!\n");
- return (FALSE);
- }
-
- /* get each word on the line */
- for (wcnt = 0; skip_spaces(); wcnt++)
- if (get_word() == NIL)
- return (FALSE);
- words[wcnt] = NIL;
-
- /* check for a blank line */
- if (wcnt == 0) {
- trm_str("Speak up! I can't hear you!\n");
- return (FALSE);
- }
-
- /* point to the first word and return successfully */
- wptr = words;
- return (TRUE);
- }
-
- /* skip_spaces - skip leading spaces */
- int skip_spaces()
- {
- while (spacep(*lptr))
- lptr++;
- return (*lptr != EOS);
- }
-
- /* show_noun - show a noun phrase */
- show_noun(n)
- int n;
- {
- int adj,*p;
-
- /* print the adjectives */
- for (p = adjectives[n-1], adj = FALSE; *p; p++, adj = TRUE) {
- if (adj) trm_chr(' ');
- trm_str(wtext[anums[p-adjs]]);
- }
-
- /* print the noun */
- if (adj) trm_chr(' ');
- trm_str(wtext[nnums[n-1]]);
- }
-
- /* get_word - get the next word */
- int get_word()
- {
- int ch;
-
- /* get the next word */
- for (wtext[wcnt] = lptr; (ch = *lptr) != EOS && !spacep(ch); )
- *lptr++ = (isupper(ch) ? tolower(ch) : ch);
- if (*lptr != EOS) *lptr++ = EOS;
-
- /* look up the word */
- if (words[wcnt] = findword(wtext[wcnt]))
- return (words[wcnt]);
- else {
- trm_str("I don't know the word \"");
- trm_str(wtext[wcnt]);
- trm_str("\".\n");
- return (NIL);
- }
- }
-
- /* spacep - is this character a space? */
- int spacep(ch)
- int ch;
- {
- return (ch == ' ' || ch == ',' || ch == '.');
- }
-
- /* parse_error - announce a parsing error */
- parse_error()
- {
- trm_str("I don't understand.\n");
- }
-